package com.treeliked.udpdemo.page.p1;

import com.treeliked.udpdemo.cs.UdpClient;
import com.treeliked.udpdemo.cs.UdpServer;
import com.treeliked.udpdemo.model.Message;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.io.IOException;
import java.text.SimpleDateFormat;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.text.DefaultCaret;
import lombok.Data;


/**
 * 服务器端页面
 *
 * @author lss
 * @date 2019-01-03, Thu
 */
@SuppressWarnings("Duplicates")
@Data
public class Client {

  /**
   * 屏幕宽度
   */
  private static final int SCREEN_WIDTH = Toolkit.getDefaultToolkit().getScreenSize().width;

  /**
   * 页面宽度
   */
  private static final int FRAME_WIDTH = 1000;

  /**
   * 屏幕高度
   */
  private static final int SCREEN_HEIGHT = Toolkit.getDefaultToolkit().getScreenSize().height;

  /**
   * 页面高度
   */
  private static final int FRAME_HEIGHT = 618;


  public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


  private static long RECEIVE_NUM_AMOUNT = 0;
  private static long SEND_NUM_AMOUNT = 0;

  private JPanel container;
  private JPanel infoContainer;
  private JLabel portInfoPanel;
  private JLabel receiveInfoPanel;
  private JLabel sendInfoPanel;
  private JTextArea messageArea;
  private JScrollPane messageScrollPPane;
  private JPanel messagePaneContainer;
  private JComboBox sendMsgChooser;
  private JButton sendMsgBtn;
  private JTextArea sendMsgTextArea;
  private JButton exitBtn;


  public void addReceiveMessageAmount() {
    RECEIVE_NUM_AMOUNT++;
    EventQueue.invokeLater(() -> receiveInfoPanel.setText("已接收消息数：" + RECEIVE_NUM_AMOUNT));
  }

  public void addSendMessageAmount() {
    SEND_NUM_AMOUNT++;
    EventQueue.invokeLater(() -> sendInfoPanel.setText("已发送消息数：" + SEND_NUM_AMOUNT));
  }

  public void addReceiveMessage(Message msg) {
    EventQueue.invokeLater(() ->
        messageArea.append(
            "ID: " + msg.getId() + "\t源端口: " + msg.getSrcPost() + "\t内容: " + msg.getContent() + "\t发送时间: " + format
                .format(msg.getSendTime()) + "\t类型: " + (msg.getMsgType() == Message.MESSAGE_TYPE_COMMON ? "普通"
                : (msg.getAckResult() == Message.ACK_RESULT_OK ? "ACK 成功" : "ACK 重发")) + "\n\n")
    );
  }

  public static void main(String[] args) throws IOException {
    JFrame frame = new JFrame("UDP 客户端 V0.0.1");

    Client client = new Client();
    UdpClient uc = new UdpClient(8881, UdpServer.DEFAULT_SERVER_PORT, client);
    uc.startReceive();
    client.init(uc);

    frame.setContentPane(client.container);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setBounds((SCREEN_WIDTH - FRAME_WIDTH) / 2, (SCREEN_HEIGHT - FRAME_HEIGHT) / 2, FRAME_WIDTH, FRAME_HEIGHT);
    frame.setVisible(true);
  }


  @SuppressWarnings("unchecked")
  public void init(UdpClient udpClient) {

    // 设置显示文字
    portInfoPanel.setText("当前端口号: " + udpClient.getPortNum());
    receiveInfoPanel.setText("已接收消息：");
    sendInfoPanel.setText("已发送消息：");

    // 显示垂直滚动条并始终保持在最下方
    messageScrollPPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    DefaultCaret caret = (DefaultCaret) messageArea.getCaret();
    caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

    // 添加本端口以外的其他8880-8889 的所有端口
    for (int i = 0; i < 10; i++) {
      int p = UdpServer.DEFAULT_SERVER_PORT + i;
      if (p == udpClient.getPortNum()) {
        continue;
      }
      sendMsgChooser.addItem(p);
    }

    // 退出监听
    exitBtn.addActionListener(e -> System.exit(0));

    // 发送监听
    sendMsgBtn.addActionListener(e -> {
      int destPort = (int) sendMsgChooser.getSelectedItem();
      String content = sendMsgTextArea.getText();
      if (content == null || content.length() == 0) {
        return;
      }
      Message msg = new Message(udpClient.getPortNum(), destPort);
      msg.setContent(content);
      msg.setMsgType(Message.MESSAGE_TYPE_COMMON);
      try {
        udpClient.sendMessage(msg);
        showAlert("发送成功");
      } catch (IOException ignored) {
        showAlert("IO异常");
      }
    });
  }

  public void showAlert(String str) {
    JOptionPane.showMessageDialog(this.container, str);
  }


}
